package com.yc;

import com.yc.web.LoginInterceptor;
import com.yc.web.TimeConverter;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;
import javax.sql.DataSource;


@Configuration
@ComponentScan(basePackages = "com.yc")
@MapperScan("com.yc.dao")            //我们是通过  interface来自动生成mapper 的class字节码的，所以只要配置 MapperScan即可.

@EnableTransactionManagement

// <mvc:annotation-driven></mvc:annotation-driven> 的替代标签是  @EnableWebMvc
@EnableWebMvc
public class AppConfig implements WebMvcConfigurer {

    // 添加过滤器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 静态资源链接 暂时不支持, 在 SpringBoot 中实现
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/withdraw.do","/find","/withdraw.html");
    }

    // 添加 类型转换器 和 格式转换器的 注册器
    @Override
    public void addFormatters(FormatterRegistry registry) {
        System.out.println("========= addFormatters ========");
        registry.addConverter(new TimeConverter());
    }

    @Bean   //标准jdbc数据源: 以下是写硬代码来配置数据源的， 生产不可用
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/banks?useUnicode=yes&characterEncoding=utf8&serverTimeZone=UTC&useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("a");
        return dataSource;
    }

    @Bean   //标准jdbc数据源   以属性文件的形式来配置的   // DI
    public DataSource dataSource2(DataSourcesConfig dsc) {    //注意，由spring DI进来数据源
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(dsc.getDriverName());
        dataSource.setUrl(dsc.getUrl());
        dataSource.setUsername(dsc.getUsername());
        dataSource.setPassword(dsc.getPassword());
        return dataSource;
    }


//    @Bean
//    @Resource(name="dataSource2")     //DI
//    public SqlSessionFactory sqlSessionFactory(   DataSource dataSource     ) throws Exception {
//        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
//        factoryBean.setDataSource(    dataSource   );
//        return factoryBean.getObject();
//    }

    //配置sqlSessionFactory
    @Bean
    @Resource(name = "dataSource2")
    public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
        //在spring和Mybatis整合中采用mybatis提供的SQLSessionFactoryBean对象
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //为sqlSessionFatoryBean设置连接池属性
        //sqlSessionFactoryBean.setDataSource(dataSource());
        sqlSessionFactoryBean.setDataSource(dataSource);
        //TODO: 注意: 如果是通过mapper.xml文件配置  sql映射 的，则配置以下 MapperLocation扫描....
        //获取PathMatchingResourcePatternResolver对象为扫描mapper文件做准备
        // PathMatchingResourcePatternResolver path = new PathMatchingResourcePatternResolver();
        //设置mapper文件位置
        // sqlSessionFactoryBean.setMapperLocations(path.getResources("classpath*:com/yc/dao/**/*.xml"));
        //为javaBean对象设置别名
        sqlSessionFactoryBean.setTypeAliasesPackage("com.yc.bean");
        sqlSessionFactoryBean.setConfiguration(configuration());
        //返回SqlSessionFactory对象
        return sqlSessionFactoryBean.getObject();
    }

    //mybatis使用的配置信息 的bean
    @Bean
    public org.apache.ibatis.session.Configuration configuration() {
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setLogImpl(StdOutImpl.class);
        //configuration.setMapUnderscoreToCamelCase(true);
        return configuration;
    }


    @Bean
    @Resource(name = "dataSource2")   //  mybatis使用的是标准的事务管理器
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    //不同的框架应采用spring规定的不同的事务管理器.    事务管理器由spring定义了一套接口:
    // 事务：  isolation隔离级别     timeout     readonly: ...


}
